using System;
using System.IO;
using System.Xml;

namespace CodeBackpack.Plist
{
    public class PropertyListXmlWriter : PropertyListWriter
    {
        internal static readonly String DtdPubid = "-//Apple Computer//DTD PLIST 1.0//EN";
        internal static readonly String DtdSysid = "http://www.apple.com/DTDs/PropertyList-1.0.dtd";
        private readonly XmlWriter xmlWriter;

        public PropertyListXmlWriter(TextWriter textWriter)
        {
            if (textWriter == null)
            {
                throw new ArgumentNullException("textWriter");
            }
            XmlWriterSettings settings = new XmlWriterSettings();
            settings.Indent = true;
            xmlWriter = XmlWriter.Create(textWriter, settings);
        }

        public override void Dispose()
        {
            (xmlWriter as IDisposable).Dispose();
        }

        public override void WriteProlog()
        {
            xmlWriter.WriteDocType(XmlTags.Plist, DtdPubid, DtdSysid, null);
            xmlWriter.WriteStartElement(XmlTags.Plist);
            xmlWriter.WriteAttributeString(XmlTags.VersionAttr, "1.0");
        }

        public override void WriteEpilog()
        {
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(byte[] value)
        {
            xmlWriter.WriteStartElement(XmlTags.Data);
            xmlWriter.WriteBase64(value, 0, value.Length);
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(String value)
        {
            xmlWriter.WriteElementString(XmlTags.String, value);
        }

        public override void WriteScalar(int value)
        {
            xmlWriter.WriteStartElement(XmlTags.Integer);
            xmlWriter.WriteValue(value);
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(long value)
        {
            xmlWriter.WriteStartElement(XmlTags.Integer);
            xmlWriter.WriteValue(value);
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(double value)
        {
            xmlWriter.WriteStartElement(XmlTags.Real);
            xmlWriter.WriteValue(value);
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(DateTime value)
        {
            xmlWriter.WriteStartElement(XmlTags.Date);
            xmlWriter.WriteValue(value);
            xmlWriter.WriteEndElement();
        }

        public override void WriteScalar(bool value)
        {
            if (value)
            {
                xmlWriter.WriteStartElement(XmlTags.True);
            }
            else
            {
                xmlWriter.WriteStartElement(XmlTags.False);
            }
            xmlWriter.WriteEndElement();
        }

        public override void WriteListStart()
        {
            xmlWriter.WriteStartElement(XmlTags.Array);
        }

        public override void WriteDictStart()
        {
            xmlWriter.WriteStartElement(XmlTags.Dict);
        }

        public override void WriteContainerEnd()
        {
            xmlWriter.WriteEndElement();
        }

        public override void WriteDictKey(String key)
        {
            xmlWriter.WriteElementString(XmlTags.Key, key);
        }
    }
}